﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleAppDemo {
    /// <summary>
    /// 线程池管理
    /// </summary>
    public class ThreadPoolManager {
        private Queue<ITask> queueTasks;
        private Queue<WorkThread> queueThreads;
        private int maxThreadNum;
        public static Semaphore s;
        public int MaxJobNum = 1000;
        public ThreadPoolManager(int maxThreadNum)
        {
            this.maxThreadNum = maxThreadNum;
            s = new Semaphore(0, MaxJobNum);
            this.queueTasks = new Queue<ITask>();
            this.queueThreads = new Queue<WorkThread>();
            CreateThreadPool();
        }
        public ThreadPoolManager() : this(10)
        { }

        public void AddTask(ITask task)
        {
            lock (queueTasks)
            {
                queueTasks.Enqueue(task);
            }
            s.Release();
        }
        public void CreateThreadPool()
        {
            lock (queueThreads)
            {
                for (int i = 0; i < maxThreadNum; i++)
                {
                    WorkThread wt = new WorkThread(ref queueTasks);
                    queueThreads.Enqueue(wt);
                }
            }
        }
        public void CloseThread()
        {
            while (queueThreads.Count > 0)
            {
                WorkThread wt = queueThreads.Dequeue();
                wt.CloseThread();
            }
        }
    }
    /// <summary>
    /// 工作线程
    /// </summary>
    public class WorkThread {
        private bool flag;
        private Queue<ITask> tasks;
        private ITask task;
        public WorkThread(ref Queue<ITask> tasks)
        {
            flag = true;
            this.tasks = tasks;
            new Thread(Run).Start();
        }
        public void Run()
        {
            while (flag && tasks != null)
            {
                while (tasks.Count == 0 && flag) ThreadPoolManager.s.WaitOne();
                Console.WriteLine("threads:{0}", Thread.CurrentThread.ManagedThreadId);
                lock (tasks)
                {
                    if (tasks.Count > 0)
                        task = tasks.Dequeue();
                }
                task.SetEnd(false);
                task.StartTask();
                if (!task.IsEnd())
                {
                    task.SetEnd(false);
                    task.EndTask();
                }
            }
        }
        public void CloseThread()
        {
            flag = false;
            if (task != null)
                task.EndTask();
        }
    }

    public interface ITask {
        void StartTask();
        void SetEnd(bool flag);
        bool IsEnd();
        void EndTask();
    }
    /// <summary>
    /// 任务
    /// </summary>
    public class TestTask : ITask {
        private bool is_end;
        private string taskName;
        public void EndTask()
        {
            is_end = true;
            Console.WriteLine("threads:{0}执行任务{1}已结束！", Thread.CurrentThread.ManagedThreadId, this.taskName);
        }
        public bool IsEnd()
        {
            return is_end;
        }
        public void Run()
        {
            Console.WriteLine("threads:{0}正在执行{1}任务...", Thread.CurrentThread.ManagedThreadId, this.taskName);
            Thread.Sleep(5000);
        }
        public void SetEnd(bool flag)
        {
            is_end = flag;
        }
        public void StartTask()
        {
            Run();
        }
        public TestTask(string taskName)
        {
            this.taskName = taskName;
        }
    }
}
